package org.lc.stk.service.support;

import java.util.ArrayList;
import java.util.List;

import org.springframework.data.jpa.domain.Specification;

import jakarta.persistence.criteria.Predicate;

/**
 * JPA动态查询条件构建工具类
 */
public class QuerySpecifications {

    /**
     * 创建like查询条件
     * @param fieldName 字段名
     * @param value 查询值
     * @return Specification
     */
    public static <T> Specification<T> like(String fieldName, String value) {
        return (root, query, builder) -> {
            if (value == null || value.trim().isEmpty()) {
                return null;
            }
            return builder.like(builder.lower(root.get(fieldName)), "%" + value.toLowerCase() + "%");
        };
    }

    /**
     * 创建等于查询条件
     * @param fieldName 字段名
     * @param value 查询值
     * @return Specification
     */
    public static <T> Specification<T> equal(String fieldName, Object value) {
        return (root, query, builder) -> {
            if (value == null) {
                return null;
            }
            return builder.equal(root.get(fieldName), value);
        };
    }

    /**
     * 合并多个查询条件
     * @param specifications 查询条件列表
     * @return 合并后的查询条件
     */
    @SafeVarargs
    public static <T> Specification<T> and(Specification<T>... specifications) {
        return (root, query, builder) -> {
            List<Predicate> predicates = new ArrayList<>();
            for (Specification<T> spec : specifications) {
                if (spec != null) {
                    Predicate predicate = spec.toPredicate(root, query, builder);
                    if (predicate != null) {
                        predicates.add(predicate);
                    }
                }
            }
            return builder.and(predicates.toArray(new Predicate[0]));
        };
    }

    /**
     * 创建OR查询条件
     * @param specifications 查询条件列表
     * @return 合并后的查询条件
     */
    @SafeVarargs
    public static <T> Specification<T> or(Specification<T>... specifications) {
        return (root, query, builder) -> {
            List<Predicate> predicates = new ArrayList<>();
            for (Specification<T> spec : specifications) {
                if (spec != null) {
                    Predicate predicate = spec.toPredicate(root, query, builder);
                    if (predicate != null) {
                        predicates.add(predicate);
                    }
                }
            }
            return builder.or(predicates.toArray(new Predicate[0]));
        };
    }
}